package com.maple.visit;

import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.maple.config.TableInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 查询语句字段追加
 *
 * @author maple
 * @version 1.0
 * @since 2021-11-22 00:50
 */
public class UpdateVisitor extends SelectVisitor {

    @Override
    public boolean visit(MySqlUpdateStatement x) {
        List<SQLUpdateSetItem> updateItemList = x.getItems();
        // 如果已经包含指定字段则忽略
        List<TableInfo> tableInfoList = getTableInfoList(x.getTableSource(), new ArrayList<>());
        filterCustomColumnTable(updateItemList, tableInfoList);
        for (TableInfo item : tableInfoList) {
            SQLUpdateSetItem sqlUpdateSetItem = new SQLUpdateSetItem();
            sqlUpdateSetItem.setColumn(new SQLPropertyExpr(StrUtil.blankToDefault(item.getAlias(),
                    item.getTableName()), BASE_COLUMN_INFO.getColumnName()));
            sqlUpdateSetItem.setValue(BASE_COLUMN_INFO.getColumnValue());
            updateItemList.add(sqlUpdateSetItem);
        }
        return super.visit(x);
    }

    private void filterCustomColumnTable(List<SQLUpdateSetItem> updateItemList, List<TableInfo> tableInfoList) {
        for (SQLUpdateSetItem sqlUpdateSetItem : updateItemList) {
            // 处理形如 A = 1 存在字段名相同的条件则去掉
            if (sqlUpdateSetItem.getColumn() instanceof SQLIdentifierExpr) {
                tableInfoList.removeIf(item -> Objects.isNull(item.getAlias()) && Objects.equals("is_delete",
                        ((SQLIdentifierExpr) sqlUpdateSetItem.getColumn()).getName()));
                continue;
            }

            // 处理形如 a.A = 1 存在别名和字段名都相同的条件则去掉
            if (sqlUpdateSetItem.getColumn() instanceof SQLPropertyExpr) {
                SQLPropertyExpr propertyExpr = (SQLPropertyExpr) sqlUpdateSetItem.getColumn();
                tableInfoList.removeIf(item -> StrUtil.equalsIgnoreCase(propertyExpr.getOwner().toString(),
                        StrUtil.blankToDefault(item.getAlias(), item.getTableName())) && StrUtil.equalsIgnoreCase(propertyExpr.getName(), BASE_COLUMN_INFO.getColumnName()));
            }
        }
    }
}
